package com.googlecode.openrtp.grizzly.rtcp.filter;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import org.glassfish.grizzly.Buffer;
import org.glassfish.grizzly.filterchain.BaseFilter;
import org.glassfish.grizzly.filterchain.FilterChainContext;
import org.glassfish.grizzly.filterchain.NextAction;
import com.googlecode.openrtp.grizzly.util.BufferUtil;
import com.googlecode.openrtp.spi.rtcp.RtcpByePacket;
import com.googlecode.openrtp.spi.rtcp.RtcpHeaderPacket;

/**
 *
 * @author jocke
 */
public class RtcpByeFilter extends BaseFilter {

    private BufferUtil bufferUtil;
    private static final Logger LOG = Logger.getLogger(RtcpByeFilter.class.getName());

    @Inject
    public RtcpByeFilter(BufferUtil bufferUtil) {
        this.bufferUtil = bufferUtil;
    }

    @Override
    public NextAction handleRead(FilterChainContext ctx) throws IOException {

        ByteBuffer longBuffer = bufferUtil.allocate(ctx, 8);

        Buffer sourceBuffer = ctx.getMessage();

        RtcpHeaderPacket headerPacket = (RtcpHeaderPacket) ctx.getAttributes().getAttribute(RtcpHeaderPacket.class.getName());

        List<Long> ssrcs = new ArrayList<>(headerPacket.getRc());

        int packetBoundry = sourceBuffer.position() + headerPacket.wordBoundry();

        for (int i = 0; i < headerPacket.getRc(); i++) {
            ssrcs.add(bufferUtil.getUnsignedIntAsLong(sourceBuffer, longBuffer));
        }

        String txt = "";

        if (sourceBuffer.position() < packetBoundry) {
             txt = bufferUtil.readString(sourceBuffer, sourceBuffer.get());
        }
        
        bufferUtil.seekBoundry(sourceBuffer);

        final RtcpByePacket packet = RtcpByePacket.create(headerPacket, ssrcs, txt);

        ctx.setMessage(packet);

        bufferUtil.release(ctx, longBuffer);

        LOG.log(Level.INFO, "RTCP bye packet has arrived {0}", packet);

        return super.handleRead(ctx);
    }

    @Override
    public NextAction handleWrite(FilterChainContext ctx) throws IOException {

        RtcpByePacket rtcpByePacket = (RtcpByePacket) ctx.getAttributes().getAttribute(RtcpByePacket.class.getName());

        Buffer sourceBuffer = ctx.getMessage();

        List<Long> ssrcs = rtcpByePacket.getSsrcs();

        for (Long ssrc : ssrcs) {
            sourceBuffer.putInt(ssrc.intValue());
        }
        
        if(rtcpByePacket.getMessage() != null) {
            byte[] bytes = rtcpByePacket.getMessage().getBytes("UTF-8");
            sourceBuffer.put((byte)bytes.length);
            sourceBuffer.put(bytes);
        }
        
        bufferUtil.paddingToBoundry(sourceBuffer);

        return super.handleWrite(ctx);
    }
}
